import os
import json
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from dotenv import load_dotenv
from modules.search_engine import StockSearchEngine
from modules.stock_data import StockDataFetcher
from modules.deepseek_api import DeepSeekAPI
from modules.result_summary import generate_summary

# 加载环境变量
load_dotenv()

class StockPredictor:
    """股票预测系统，整合搜索引擎、股票数据和DeepSeek API"""

    def __init__(self):
        """初始化股票预测系统"""
        # 检查必要的环境变量
        required_env_vars = ["ANSPIRE_API_KEY", "DEEPSEEK_API_KEY"]
        missing_vars = [var for var in required_env_vars if not os.getenv(var)]

        if missing_vars:
            raise ValueError(f"缺少必要的环境变量: {', '.join(missing_vars)}")

        # 初始化各模块
        self.search_engine = StockSearchEngine()
        self.data_fetcher = StockDataFetcher()
        self.deepseek_api = DeepSeekAPI()

    def predict_stock(self, stock_code, stock_name, days=30):
        """预测股票走势

        Args:
            stock_code: 股票代码
            stock_name: 股票名称
            days: 分析的天数，默认30天

        Returns:
            预测结果字典
        """
        print(f"\n===== 开始分析股票: {stock_name}({stock_code}) =====")

        # 1. 获取股票基本面信息（通过搜索）
        print("\n1. 正在获取股票基本面信息...")
        search_results = []
        try:
            search_results = self.search_engine.search_stock_info(stock_code, stock_name, days)
            print(f"   获取到 {len(search_results)} 条搜索结果")
        except Exception as e:
            print(f"   警告: 获取基本面信息失败: {str(e)}")
            print("   将使用空的搜索结果继续分析")

        # 2. 获取股票历史数据
        print("\n2. 正在获取股票历史数据...")
        stock_data = self.data_fetcher.fetch_stock_data(stock_code, days)
        using_mock_data = False
        
        if stock_data.empty:
            print(f"警告: 无法获取股票 {stock_code} 的真实历史数据，将使用模拟数据继续")
            # 生成模拟数据
            dates = pd.date_range(end=datetime.now(), periods=days)
            np.random.seed(42)
            base_price = 100.0
            volatility = 0.02
            returns = np.random.normal(0, volatility, len(dates))
            price_series = base_price * (1 + np.cumsum(returns))
            stock_data = pd.DataFrame({
                '日期': dates,
                'open': price_series * np.random.uniform(0.99, 1.01, len(dates)),
                'close': price_series,
                'high': price_series * np.random.uniform(1.01, 1.03, len(dates)),
                'low': price_series * np.random.uniform(0.97, 0.99, len(dates)),
                'volume': np.random.randint(1000000, 10000000, len(dates)),
                'amount': price_series * np.random.randint(1000000, 10000000, len(dates))
            })
            # 计算技术指标
            stock_data = self.data_fetcher._calculate_indicators(stock_data)
            using_mock_data = True
        
        print(f"   获取到 {len(stock_data)} 天的股票数据{' (模拟数据)' if using_mock_data else ''}")

        # 3. 使用DeepSeek分析基本面信息
        print("\n3. 正在分析基本面信息...")
        fundamental_analysis = self.deepseek_api.analyze_fundamental_data(
            stock_code, stock_name, search_results
        )
        print("   基本面分析完成")

        # 4. 使用DeepSeek分析技术面数据
        print("\n4. 正在分析技术面数据...")
        technical_analysis = self.deepseek_api.analyze_technical_data(
            stock_code, stock_name, stock_data
        )
        print("   技术面分析完成")

        # 5. 生成最终预测
        print("\n5. 正在生成最终预测...")
        final_prediction = self.deepseek_api.generate_final_prediction(
            stock_code, stock_name, fundamental_analysis, technical_analysis
        )
        print("   最终预测生成完成")

        # 6. 整合结果
        result = {
            "stock_info": {
                "code": stock_code,
                "name": stock_name
            },
            "fundamental_analysis": fundamental_analysis,
            "technical_analysis": technical_analysis,
            "final_prediction": final_prediction
        }

        return result

    def save_result(self, result, output_file=None):
        """保存分析结果到文件

        Args:
            result: 分析结果字典
            output_file: 输出文件路径，默认为"stock_analysis_{股票代码}.json"
        """
        if output_file is None:
            output_file = f"stock_analysis_{result['stock_info']['code']}.json"

        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2)

        print(f"\n分析结果已保存到: {output_file}")

    def print_summary(self, result):
        """打印分析结果摘要

        Args:
            result: 分析结果字典
        """
        stock_info = result["stock_info"]
        fundamental = result["fundamental_analysis"]
        technical = result["technical_analysis"]
        prediction = result["final_prediction"]

        print("\n===== 股票分析报告摘要 =====")
        print(f"股票: {stock_info['name']}({stock_info['code']})")

        print("\n基本面分析:")
        if "rating" in fundamental:
            print(f"评级: {fundamental['rating']}")
        if "conclusion" in fundamental:
            print(f"结论: {fundamental['conclusion']}")

        print("\n技术面分析:")
        if "rating" in technical:
            print(f"评级: {technical['rating']}")
        if "conclusion" in technical:
            print(f"结论: {technical['conclusion']}")

        print("\n综合预测:")
        if "overall_rating" in prediction:
            print(f"综合评级: {prediction['overall_rating']}")
        if "tomorrow_forecast" in prediction:
            forecast = prediction["tomorrow_forecast"]
            direction = forecast.get("预期走势", "") if isinstance(forecast, dict) else ""
            confidence = forecast.get("置信度", "") if isinstance(forecast, dict) else ""
            print(f"明日预测: {direction} (置信度: {confidence})")
        if "investment_advice" in prediction:
            print(f"投资建议: {prediction['investment_advice']}")
        if "risk_warning" in prediction:
            print(f"风险提示: {prediction['risk_warning']}")


def main():
    """主函数"""
    try:
        # 检查环境变量
        anspire_api_key = os.getenv("ANSPIRE_API_KEY")
        deepseek_api_key = os.getenv("DEEPSEEK_API_KEY")
        
        if not anspire_api_key or not deepseek_api_key:
            print("错误: 请在.env文件中设置ANSPIRE_API_KEY和DEEPSEEK_API_KEY")
            print("提示: 复制.env.example为.env，并填入你的API密钥")
            return
            
        # 创建股票预测系统
        try:
            predictor = StockPredictor()
        except Exception as e:
            print(f"初始化预测系统失败: {str(e)}")
            print("请检查您的API密钥和网络连接。")
            return

        # 获取用户输入
        print("===== 股票走势预测系统 =====")
        stock_code = input("请输入股票代码: ")
        stock_name = input("请输入股票名称: ")

        try:
            # 预测股票走势
            result = predictor.predict_stock(stock_code, stock_name)

            # 保存结果
            predictor.save_result(result)

            # 打印摘要
            predictor.print_summary(result)
            
        except Exception as e:
            print(f"\n处理股票 {stock_code} 时出现错误: {str(e)}")
            print("系统将尝试使用模拟数据继续...")
            
            # 创建一个基本的结果
            mock_result = {
                "stock_info": {
                    "code": stock_code,
                    "name": stock_name
                },
                "fundamental_analysis": {
                    "rating": "中性",
                    "conclusion": "由于无法获取真实数据，此分析基于有限信息。建议使用其他工具获取准确信息。"
                },
                "technical_analysis": {
                    "rating": "中性",
                    "conclusion": "由于无法获取真实数据，此分析基于有限信息。建议使用其他工具获取准确信息。"
                },
                "final_prediction": {
                    "overall_rating": "中性",
                    "tomorrow_forecast": {
                        "预期走势": "不确定",
                        "置信度": "50%"
                    },
                    "investment_advice": "由于数据限制，无法提供可靠的投资建议。建议使用其他工具获取准确信息。",
                    "risk_warning": "此分析基于有限数据，不应作为投资决策依据。"
                }
            }
            
            # 保存模拟结果
            output_file = f"mock_analysis_{stock_code}.json"
            with open(output_file, 'w', encoding='utf-8') as f:
                json.dump(mock_result, f, ensure_ascii=False, indent=2)
            
            print(f"\n由于错误，已生成基本分析报告: {output_file}")
            print("请注意: 此报告不应作为投资决策依据。")
            
            # 打印模拟结果摘要
            predictor.print_summary(mock_result)

    except Exception as e:
        print(f"\n系统错误: {str(e)}")
        print("请检查您的网络连接和API密钥设置。")
        
        if os.getenv("DEBUG", "").lower() == "true":
            import traceback
            traceback.print_exc()


if __name__ == "__main__":
    main()
